﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Sublimation
{
    public class Shield : GameObject
    {
        private GameObject parent;
        public GameObject Parent
        {
            get { return this.parent; }
        }

        protected float maxShieldEnergy;
        public float MaxShieldEnergy
        {
            get { return this.maxShieldEnergy; }
            set { this.maxShieldEnergy = value; }
        }

        protected float shieldEnergy;
        public float ShieldEnergy
        {
            get { return this.shieldEnergy; }
            set
            {
                this.shieldEnergy = MathHelper.Clamp(value, 0, MaxShieldEnergy);
            }
        }

        protected float shieldPerSecond;
        public float ShieldPerSecond
        {
            get { return this.shieldPerSecond; }
            set { this.shieldPerSecond = value; }
        }

        protected int regenerationDelay;
        public int RegenerationDelay
        {
            get { return this.regenerationDelay; }
            set { this.regenerationDelay = value; }
        }
        
        private const float SHIELD_SCALE_TO_PARENT = 1.35f;
        public Shield(WorldProperties worldProperties, GameObject parent,
            float maxShieldEnergy, float sheildEnergy, float shieldPerSecond, int regenerationDelay)
            : base(worldProperties)
        {
            LoadContent();

            // make sure it loads and draws
            DrawOrder = 60;
            UpdateOrder = 100; // make sure these are updated very late so they can follow the parents etc
            Visible = true;
            Enabled = true;

            Origin = new Vector2(10, 10);
            this.parent = parent;
            this.Scale = 1.0f / SPRITE_SCALE_TO_ONE;
            ScaleOverObject(parent, SHIELD_SCALE_TO_PARENT);
            this.Velocity = Vector2.Zero;

            this.MaxShieldEnergy = maxShieldEnergy;
            this.ShieldEnergy = sheildEnergy;
            this.ShieldPerSecond = shieldPerSecond;
            this.RegenerationDelay = regenerationDelay;
        }

        public Shield(WorldProperties worldProperties, GameObject parent)
            : this(worldProperties, parent, 0, 0, 0, 0)
        {
        }

        private double delayCounterMilliseconds = 0;
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            // mirror the parents movements
            CentreOnObject(parent);
            AlignOriginWithObject(parent);
            this.Rotation = parent.Rotation;
            
            // regenerate energy
            delayCounterMilliseconds = Math.Max(delayCounterMilliseconds - gameTime.ElapsedGameTime.TotalMilliseconds, 0);
            if (delayCounterMilliseconds == 0)
            {
                ShieldEnergy += ShieldPerSecond * (float)gameTime.ElapsedGameTime.TotalSeconds;
            }
            
            // only display if it has health
            if (ShieldEnergy == 0) Visible = false;
            else Visible = true;
        }

        private Color shieldBlend = new Color(255, 255, 255, 150);
        public override void Draw(GameTime gameTime)
        {
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            spriteBatch.Draw(Sprite, Position, null, shieldBlend, Rotation, Origin, Scale, SpriteEffects.None, 1);
            spriteBatch.End();
        }

        // the size of a shield frame
        private const float SPRITE_SCALE_TO_ONE = 100f;
        protected override void LoadContent()
        {
            base.LoadContent();

            Sprite = Game.Content.Load<Texture2D>("Sprites\\shield");
        }

        public override void ApplyDamage(float damage)
        {
            base.ApplyDamage(damage);

            // remove health from the shield
            ShieldEnergy -= damage;

            // collapse the shield
            if (ShieldEnergy == 0) Collapse();
        }

        protected void Collapse()
        {
            // start a counter before it starts regenerating (so theres a delay)
            delayCounterMilliseconds += RegenerationDelay;

            // play a collapsing animation and 
            //TODO: collapse the shield animation - a special looking bluey explosion
        }
    }
}
